package net.zxteam.reusable.java.io;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import net.zxteam.reusable.java.IllegalArgumentNullException;

public final class File {

	public static java.io.File getRelativeFile(java.io.File path, java.io.File relativeRootDirectory) {
		
		if(path == null)
			throw new IllegalArgumentNullException("path");

		if(relativeRootDirectory == null)
			throw new IllegalArgumentNullException("relativeRootDirectory");

		if(!relativeRootDirectory.isDirectory())
			throw new IllegalArgumentException("relativeRootDirectory should be directory");

		String fileStr = path.getAbsolutePath();
		String relativeRootStr = relativeRootDirectory.getAbsolutePath();
		if(!fileStr.startsWith(relativeRootStr))
			throw new IllegalArgumentException("File: '" + fileStr + "' is not related to Directory: '" + relativeRootStr + "'");

		String relativeFileStr = fileStr.substring(relativeRootStr.length());
		if(relativeFileStr.startsWith("\\")) relativeFileStr = relativeFileStr.substring(1);

		return new java.io.File(relativeFileStr);
	}

	/**
	 * Compare MD5 hash-sum of two files. Use something like
	 * {@link #newTempDirectory()} to give java.io.File result
	 * @return true - if hash-sum is equal, otherwise false
	 * @throws NoSuchAlgorithmException 
	 * @throws IOException if there is an error creating the temporary directory
	 */
	public static boolean hashTestMD5(java.io.File file1, java.io.File file2) throws NoSuchAlgorithmException, IOException {

		byte[] hash1 = getFileHashMD5(file1);
		byte[] hash2 = getFileHashMD5(file2);		

		for(byte index = 0; index < 16; index++)
			if(hash1[index] != hash2[index])
				return true;
		
		return false;
	}

	public static byte[] getFileHashMD5(java.io.File file) throws NoSuchAlgorithmException, IOException {

		MessageDigest md = MessageDigest.getInstance("MD5");
		InputStream is = new FileInputStream(file);
		try {
			  is = new DigestInputStream(is, md);
			  //int read;
			  byte[] buffer = new byte[8192];
			  while(is.read(buffer) > 0) {
			  // read stream to EOF as normal...
			  }
		}
		finally {
			  is.close();
		}

		return md.digest();
	}

	public static String getFileHashMD5Str(java.io.File file) throws NoSuchAlgorithmException, IOException {

		byte[] hash = getFileHashMD5(file);
		String signature = new BigInteger(1, hash).toString(16);

		return signature;
	}
}
